package io.netty.client.Bio;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class Socketservice {
    /**
     * bio服务器端
     * 1， 服务器端是ServerSocket，然后监听端口
     */

    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket(8989);
        // 一直去获取客户端
        while (true){
            /**
             * 1，线程里面只有一个阻塞，相当于非阻塞，不会影响线程的执行。
             *,2，accept是接收请求建立链接，所以有多个个请求进来，它就能建立多少个链接。只要接收的线程不阻塞在其他位置。
             * 如果accept和read使用一个线程，accept会接收多个请求，它不会阻塞，因为它就是为了接收请求。它一直在等待着接收请求。
             * 但是如果accept和read是在一个线程内，只要read阻塞，accept对应的代码不会执行，所以accept不会继续接收请求。
             *
             * Bio：阻塞模式，线程的个数决定了性能
             * 1，用一个线程接收链接，和接收和返回数据。 （阻塞之后，第二个请求是进不来的）
             * 2，用一个线程接收，新创建一个线程去接收和返回数据。（每个线程只处理一个阻塞任务，就不会阻塞，但是1w个请求，就要创建1w个线程，容易oom）
             * 3，用一个线程接收，创建一个线程池，去接收和返回数据。(每个线程处理一个任务，不会阻塞，同时10W个请求，重复使用同一个线程，但是100个线程，处理速度还是比较慢，提高性能还是需要扩大线程池)
             *
             * NIO：非阻塞，意味着一直会占用cpu资源，所以还是要解决占用cpu问题，是通过阻塞和事件驱动来解决。
             * 1，用一个线程接收，和接收和返回数据（不阻塞，每个请求进来，还是用同一个线程，因为不阻塞，所以这个线程一个在占用cpu资源一直在循环的遍历，同时当接收和响应时间比较长的任务，一直占用线程，也不会接收新的响应）
             * （用一个线程链接，接收和响应 有三个问题： 1，因为非阻塞，一直占用cpu,即使没有请求过来。2，大任务单个线程处理时间长，导致不能处理其他任务。
             * 3，多个channel，就需要遍历的集合中的所有channel，看哪个channel有数据需要接收和处理，如果只遍历需要接收和响应的链接。）
             *
             * 为什么要使用事件驱动？
             * 2，改变思路，不再关心创建的线程多少。创建两个集合，不去一直遍历是否有链接，有链接就放到集合中。再创建一个读写集合，有读写任务才会放到这个集合中。只遍历这个有读写的集合，如果没有读写事件，
             * 就阻塞，释放cpu资源。（事件驱动来解决）
             *
             *
             *
             * 使用io多路复用技术，来解决多线程问题，创建线程多的问题
              */
            Socket accept = serverSocket.accept();
            System.out.println("接收客户端链接");
            handler(accept);
        }
    }
    /**
     * 接收客户端信息
     */
    private static void handler(Socket clientSocket) throws IOException {
        byte[] bytes = new byte[1024];
        /**
         * 第一个请求进来，阻塞到这里。 第二个请求是进不到这里的。因为这里是用的一个线程，主线程阻塞到了这里
         * 所以为什么不能使用bio，阻塞io，是因为阻塞的线程，是不可用处理其他任务的，它阻塞到这里，放弃了cpu资源，其他请求进来不会用响应
         */
        int read = clientSocket.getInputStream().read(bytes);
        System.out.println("读取数据完成");
        if (read != -1) {
            System.out.println("接收客户端消息"+new String(bytes,0,read));
        }
        System.out.println("一次读取完成");
    }
}
